import { Injectable } from '@nestjs/common';
import { CreateArticleDto, GetArticleDto } from './dto/create-article.dto';
import { UpdateArticleDto } from './dto/update-article.dto';
import { Article } from 'src/database/article.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserService } from 'src/user/user.service';
import { User } from 'src/database/user.entity';
import { Tags } from 'src/database/tags.entity';

@Injectable()
export class ArticleService {
  constructor(
    @InjectRepository(Article) private articleRepository: Repository<Article>,
    @InjectRepository(Tags) private tagsRepository: Repository<Tags>,
    @InjectRepository(User) private userRepository: Repository<User>,
    private readonly userService: UserService,
  ) {}
  async create(createArticleDto: CreateArticleDto, token: string) {
    const userInfo = await this.userService.getTokenInfo(token);
    const article = new Article();
    const user = new User();
    user.id = userInfo.id;
    article.user = user;
    article.title = article.title = createArticleDto.title;
    article.content = createArticleDto.content;
    article.imgUrl = createArticleDto.imgUrl;
    article.desc = createArticleDto.desc;
    const tags = await this.tagsRepository.findByIds(createArticleDto.tags);
    article.tags = tags;
    return this.articleRepository.save(article);
  }

  async findAll(getArticls: GetArticleDto) {
    const [articles, total] = await this.articleRepository
      .createQueryBuilder('article')
      .leftJoinAndSelect('article.tags', 'tags')
      .leftJoinAndSelect('article.user', 'user')
      .where('article.title LIKE :title', {
        title: `%${getArticls.title}%`,
      })
      .skip((getArticls.page - 1) * getArticls.pageSize)
      .take(getArticls.pageSize)
      .getManyAndCount();
    return {
      total,
      list: articles,
    };
  }

  findOne(id: number) {
    return this.articleRepository.findOne({ where: { id } });
  }

  async update(id: number, updateArticleDto: UpdateArticleDto) {
    const article = await this.articleRepository.findOne({ where: { id } });
    for (const key in updateArticleDto) {
      article[key] = updateArticleDto[key];
    }
    const tags = await this.tagsRepository.findByIds(updateArticleDto.tags);
    article.tags = tags;
    return this.articleRepository.save(article);
  }

  remove(id: number) {
    return this.articleRepository.delete(id);
  }
  async collect(id: number, token: string) {
    const tokenInfo = await this.userService.getTokenInfo(token);
    const user = await this.userRepository.findOne({
      relations: ['collectArticles'],
      where: { id: tokenInfo.id },
    });
    const article = await this.articleRepository.findOne({
      where: { id },
      relations: ['collectUsers'],
    });
    const isCollect = user.collectArticles.some((item) => item.id === id);
    if (isCollect) {
      // 取消收藏
      article.collectUsers = article.collectUsers.filter(
        (el) => el.id !== user.id,
      );
    } else {
      // 收藏
      article.collectUsers = [...article.collectUsers, user];
    }
    return this.articleRepository.save(article);
  }

  async getUserCollect(token: string) {
    const tokenInfo = await this.userService.getTokenInfo(token);
    const res = await this.articleRepository
      .createQueryBuilder('article')
      .leftJoinAndSelect('article.collectUsers', 'user')
      .leftJoinAndSelect('article.tags', 'tags')
      .leftJoinAndSelect('article.user', 'author')
      .where('user.id = :id', { id: tokenInfo.id })
      .getMany();
    return res;
  }
}
